#include "fields.hpp"
#include <memory>
#include <functional>
using namespace ns_fields;

namespace ns_rpc
{
    class BaseMessage
    {
    public:
        using ptr = std::shared_ptr<BaseMessage>;
        virtual ~BaseMessage()
        {
        }

        virtual void Setid(std::string id)
        {
            _sid = id;
        }
        virtual void SetMtype(Mtype type)
        {
            _mtype = type;
        }
        virtual Mtype GetMtype()
        {
            return _mtype;
        }
        virtual std::string Getid()
        {
            return _sid;
        }
        virtual std::string serialize() = 0;
        virtual bool unserialize(const std::string& body) = 0;
        virtual bool check() = 0;

    private:
        Mtype _mtype;
        std::string _sid;
    };

    class BaseBuffer
    {
    public:
        using ptr = std::shared_ptr<BaseBuffer>;

        virtual size_t Readablebytes() = 0;  // 返回当前缓冲区有多少数据
        virtual int32_t Peekint32() = 0;     // 取出4字节数据
        virtual void Retrieveint32() = 0; // 删除4字节数据
        virtual int32_t Readint32() = 0;     // 上面俩结合
        virtual std::string RetrieveAsstring(size_t len) = 0;
    };

    class BaseProtocol
    {
    public:
        using ptr = std::shared_ptr<BaseProtocol>;
        virtual bool Canprocessed(const BaseBuffer::ptr &buf) = 0;
        virtual bool Onmessage(BaseBuffer::ptr &buf, BaseMessage::ptr &msg) = 0;
        virtual std::string Serialize(const BaseMessage::ptr &msg) = 0;
    };

    class BaseConnection
    {
    public:
        using ptr = std::shared_ptr<BaseConnection>;
        virtual void Send(const BaseMessage::ptr &msg) = 0;
        virtual void shutdown() = 0;
        virtual bool connected() = 0;
        // private:
        //     BaseProtocol::ptr _protocol; //作用：序列化发来的msg，Send内部序列化完，再进行操作 (让派生类实现吧)
    };

    using ConnectionCallback = std::function<void(const BaseConnection::ptr &)>;
    using CloseCallback = std::function<void(const BaseConnection::ptr &)>;
    using MessageCallback = std::function<void(const BaseConnection::ptr &, BaseMessage::ptr &)>;

    class BaseServer
    {
    public:
        using ptr = std::shared_ptr<BaseServer>;
        virtual void SetConnectionCallback(const ConnectionCallback &cb)
        {
            _cb_connect = cb;
        }
        virtual void SetCloseCallback(const CloseCallback &cb)
        {
            _cb_close = cb;
        }
        virtual void SetMessageCallback(const MessageCallback &cb)
        {
            _cb_message = cb;
        }
        virtual void start() = 0;

    protected:
        ConnectionCallback _cb_connect;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };

    class BaseClient
    {
    public:
        using ptr = std::shared_ptr<BaseClient>;
        virtual void SetConnectionCallback(const ConnectionCallback &cb)
        {
            _cb_connect = cb;
        }
        virtual void SetCloseCallback(const CloseCallback &cb)
        {
            _cb_close = cb;
        }
        virtual void SetMessageCallback(const MessageCallback &cb)
        {
            _cb_message = cb;
        }
        virtual void connect() = 0;
        virtual bool send(const BaseMessage::ptr &msg) = 0;
        virtual void shutdown() = 0;
        virtual BaseConnection::ptr connection() = 0;
        virtual bool connected() = 0;

    protected:
        ConnectionCallback _cb_connect;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };
};